(function() {

    var BigInteger = function(n) {
        this.integers = [];
        if(n) {
            this._convert(n);
        } else {
            this.integers.push(0);
        }
    }
    
    BigInteger.STEP = 1000;
    
    BigInteger.prototype._convert = function(n) {
        var tmp=n, i;
        while(tmp>0) {
            i = tmp%BigInteger.STEP;
            this.integers.push(i);
            tmp = (tmp-i)/BigInteger.STEP;
        }
        return this;
    };
    
    BigInteger.prototype.add = function(nOther) {
        if(!(nOther instanceof BigInteger)) {
            nOther = new BigInteger(nOther);
        }
        var maxSize = Math.max(this.getSize(), nOther.getSize()), tmp=0, b;
        for(var i=0; i< maxSize; i++) {
            tmp = this.getInteger(i) + nOther.getInteger(i) + tmp;
            b = tmp%BigInteger.STEP;
            this.integers[i] = b;
            tmp = (tmp-b)/BigInteger.STEP;
        }
        this._convert(tmp);
        return this;
    };
    
    BigInteger.prototype.times = function(n) {
        var maxSize = this.getSize(), tmp=0, b;
        for(var i=0; i< maxSize; i++) {
            tmp = this.getInteger(i) * n + tmp;
            b = tmp%BigInteger.STEP;
            this.integers[i] = b;
            tmp = (tmp-b)/BigInteger.STEP;
        }
        this._convert(tmp);
        return this;
    };
    
    BigInteger.prototype.toString = function() {
        var size = this.integers.length;
        var s = [this.integers[size-1].toString()], tmp;
        for(var i=size-2; i>=0; i--) {
            var tmp = (this.integers[i]+1000).toString().substr(1);
            s.push(tmp);
        }
        return s.join("");
    };
    
    BigInteger.prototype.print = function() {
        JEuler.system.print(this.integers);
    };
    
    BigInteger.prototype.clone = function() {
        var clone = new BigInteger(0);
        for(var i=0; i< this.getSize(); i++) {
            clone.integers[i] = this.integers[i];
        }
        return clone;
    };
    
    BigInteger.prototype.getSize = function() {
        return this.integers.length;
    };
    
    BigInteger.prototype.getDigitCount = function() {
        var head = this.integers[this.integers.length-1];
        var i = head>=100 ? 3 : ((head>=10) ? 2 : 1);
        return (this.integers.length-1)*3 + i;
    };
    
    BigInteger.prototype.getInteger = function(i) {
        return this.integers[i] || 0;
    };
    
    JEuler.math.BigInteger = BigInteger;

})();
